<?php

abstract class GDGE_Location_Abstract implements GDGE_Location_Interface
{
	
	private $_identifier = null;
	private $_superLocation = false;
	private $_subLocations = false;
	
	
	/**
	 * 
	 * Construct the location
	 * @param mixed $identifier
	 */
	public function GDGE_Location_Abstract($identifier)
	{
		$this->_identifier = $identifier;
	}
	
	public function getIdentifier()
	{
		return $this->_identifier;
	}
	
	/**
	 * 
	 * Override to return super location for this location,
	 * or null if this is a top level location
	 * @return GDGE_Location_Interface
	 */
	abstract protected function _fetchSuperLocation();
	
	/**
	 * 
	 * Override to return an array of sublocations, or
	 * empty array if no sublocations
	 * @return array
	 */
	abstract protected function _fetchSubLocations();
		
	public function getSubLocations()
	{
		if ($this->_subLocations === false) {
			$this->_subLocations = $this->_fetchSubLocations();
		}
		return $this->_subLocations;
	}
	public function getSuperLocation()
	{
		if ($this->_superLocation === false) {
			$this->_superLocation = $this->_fetchSuperLocation();
		}
		return $this->_superLocation;
	}
	
	public function equals(GDGE_Location_Interface $location)
	{
		return ($this->getIdentifier() == $location->getIdentifier());
	}
	
	public function isPartOf(GDGE_Location_Interface $location)
	{
		if ($this->equals($location)) return true;
		$parent = $this->getSuperLocation();
		if ($parent == null) return false;
		return $parent->isPartOf($location);
	}
	
	public function contains(GDGE_Location_Interface $location)
	{
		if ($this->equals($location)) return true;
		$subs = $this->getSubLocations();
		if (!is_array($subs)) return false;
		foreach ($subs as $s) {
			if ($s->contains($location)) return true;
		}
		return false;
	}
	
}